home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Graphics Unleashed
/
PC Graphics Unleashed.iso
/
ch01
/
vesa.c
< prev
next >
Wrap
Text File
|
1993-12-06
|
5KB
|
147 lines
/**
** VESA.C ---- VESA compatible paging routines
**
** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**/
int VESA_win_write = 0; /* VESA window index of the writable page */
int VESA_win_read = (-1); /* VESA window index of the readable page */
void far paging_routine(void)
{
return;
}
void far VESA_paging_routine(void)
{
asm push ds;
asm push es;
asm mov cl,BYTE PTR cs:[driver_header.page_gran_shift];
asm mov dl,al;
asm xor dh,dh;
asm shl dx,cl; /* DX: write window (A or B) index */
asm mov al,ah;
asm xor ah,ah;
asm shl ax,cl; /* AX: read window index */
asm mov bx,WORD PTR cs:[VESA_win_write]; /* index (A or B) of write window */
asm cmp bx,(-1); /* set it ? */
asm je set_read_window;
asm push ax; /* save read window */
asm mov ax,0x4f05;
asm call DWORD PTR cs:[driver_header.VESA_paging_fnc];
asm pop ax;
set_read_window:
asm mov bx,WORD PTR cs:[VESA_win_read]; /* index (A or B) of read window */
asm cmp bx,(-1); /* set it ? */
asm je paging_done;
asm mov dx,ax;
asm mov ax,0x4f05;
asm call DWORD PTR cs:[driver_header.VESA_paging_fnc];
paging_done:
asm pop es;
asm pop ds;
asm mov al,8; /* reconfig GR CTRL port for mask writes */
asm mov dx,0x3ce; /* GRX expects it in 16 color modes, and */
asm out dx,al; /* the paging func may have changed it */
return;
}
int setup_VESA_paging(GrModeEntry *md)
{
ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
int winsize,wingran,Aattr,Battr,Sdiff;
if(!mb || !(mb->ModeAttributes & MODE_ISGRAPHICS)) {
VESA_win_read = (-1);
VESA_win_write = (-1);
driver_header.VESA_paging_fnc = 0L;
driver_header.paging_routine = FP_OFF(paging_routine);
return(GRD_NO_RW);
}
/* size and granularity must be pwr of 2! */
for(winsize = 0; (1 << winsize) < mb->WinSize; winsize++) ;
for(wingran = 0; (1 << wingran) < mb->WinGranularity; wingran++) ;
if((1 << winsize) != mb->WinSize) return(-1);
if((1 << wingran) != mb->WinGranularity) return(-1);
/* check window attributes */
Aattr = mb->WinAAttributes;
Battr = mb->WinBAttributes;
Sdiff = mb->WinBSegment - mb->WinASegment;
Aattr &= (Aattr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
Battr &= (Battr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
/* cases with two adjacent split R/W pages (ATI) */
if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
(Battr == (WIN_READABLE | WIN_WRITABLE)) &&
(Sdiff == ((1024 / 16) << winsize))) {
driver_header.wr_page_start = mb->WinASegment;
driver_header.rd_page_start = mb->WinBSegment;
VESA_win_write = 0;
VESA_win_read = 1;
}
else if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
(Battr == (WIN_READABLE | WIN_WRITABLE)) &&
(Sdiff == ((-1024 / 16) << winsize))) {
driver_header.wr_page_start = mb->WinBSegment;
driver_header.rd_page_start = mb->WinASegment;
VESA_win_write = 1;
VESA_win_read = 0;
}
/* cases with one full R and one full W page (Tseng 4000) */
else if((Aattr & WIN_READABLE) &&
(Battr & WIN_WRITABLE) &&
(Sdiff == 0)) {
driver_header.wr_page_start = mb->WinBSegment;
driver_header.rd_page_start = mb->WinASegment;
VESA_win_write = 1;
VESA_win_read = 0;
}
else if((Aattr & WIN_WRITABLE) &&
(Battr & WIN_READABLE) &&
(Sdiff == 0)) {
driver_header.wr_page_start = mb->WinASegment;
driver_header.rd_page_start = mb->WinBSegment;
VESA_win_write = 0;
VESA_win_read = 1;
}
/* single page cases (Trident) */
else if(Aattr == (WIN_WRITABLE | WIN_READABLE)) {
driver_header.wr_page_start = mb->WinASegment;
driver_header.rd_page_start = 0xffff;
VESA_win_write = 0;
VESA_win_read = (-1);
}
else if(Battr == (WIN_WRITABLE | WIN_READABLE)) {
driver_header.wr_page_start = mb->WinBSegment;
driver_header.rd_page_start = 0xffff;
VESA_win_write = 1;
VESA_win_read = (-1);
}
/* cannot use the paging scheme of this card */
else return(-1);
/* setup header variables */
driver_header.page_size_shift = winsize - 2; /* in 4kByte units */
driver_header.page_gran_shift = winsize - wingran;
driver_header.line_offset = mb->BytesPerScanLine;
driver_header.VESA_paging_fnc = mb->WinFuncPtr;
driver_header.paging_routine = FP_OFF(VESA_paging_routine);
return((VESA_win_read == (-1)) ? GRD_NO_RW : GRD_RW_64K);
}